﻿using System.Collections;

namespace Draco.DataStructure
{
    /// <summary>
    /// 顺序循环队列
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    public class D_SeqQueue<T> : IEnumerable
    {
        private T[] data;
        private int front; //对首
        private int rear; //队尾

        public int Count { get; private set; }

        public T this[int index]
        {
            get
            {
                if (index < 0 && index >= Count) return default(T);
                int tempFront = (front + 1 + index) % Count;
                return data[tempFront];
            }
        }

        public D_SeqQueue(int size)
        {
            data = new T[size];
            front = -1;
            rear = -1;
            Count = 0;
        }

        public D_SeqQueue() : this(10) { }

        public bool IsEmpty()
        {
            return Count == 0;
        }

        public bool IsFull()
        {
            return Count == data.Length;
        }

        public void Clear()
        {
            Count = 0;
            front = -1;
            rear = -1;
        }

        public void Enqueue(T item)
        {
            if (Count == data.Length)
            {
                //超出队列容纳空间
                return;
            }
            else
            {
                if (rear == data.Length - 1)
                {
                    data[0] = item;
                    rear = 0;
                }
                else
                {
                    data[++rear] = item;
                }
                Count++;
            }
        }

        public T Dequeue()
        {
            if (Count > 0)
            {
                T temp;
                if (front == data.Length - 1)
                {
                    temp = data[0];
                    front = 0;
                }
                else
                {
                    temp = data[++front];
                }
                Count--;
                return temp;
            }
            else
            {
                //队列为空
                return default(T);
            }
        }

        public T Peek()
        {
            if (Count > 0)
            {
                T temp = data[front + 1];
                return temp;
            }
            else
            {
                //队列为空
                return default(T);
            }
        }

        public bool Contains(T item)
        {
            foreach (T t in this)
            {
                if (item.Equals(t))
                    return true;
            }
            return false;
        }

        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < Count; i++)
            {
                yield return data[i];
            }
        }
    }
}
